package indi.flynn.zhouyi.param;

import com.google.common.collect.Lists;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 参数解析工具类
 * 提供安全的Map参数解析和类型转换，支持自动trim字符串
 */
public class ParamUtils {

    /**
     * 安全获取并处理Map中的字符串值
     * @param map 参数Map
     * @param key 参数键
     * @return trim处理后的字符串，若为空串则返回null
     */
    private static String getTrimmedValue(Map<String, ?> map, String key) {
        String value = MapUtils.getString(map, key);
        return StringUtils.trimToNull(value);
    }

    // ==================== String ====================

    /**
     * 获取String参数，自动trim并处理空值
     * @param map 参数Map
     * @param key 参数键
     * @param defaultValue 默认值
     * @return 处理后的字符串，若为空则返回默认值
     */
    public static String getStringWithTrim(Map<String, ?> map, String key, String defaultValue) {
        String value = getTrimmedValue(map, key);
        return value != null ? value : defaultValue;
    }

    // ==================== Integer ====================

    /**
     * 获取Integer参数，自动trim字符串并处理空值
     * @param map 参数Map
     * @param key 参数键
     * @param defaultValue 默认值
     * @return 转换后的Integer，失败或空值返回默认值
     */
    public static int getIntegerWithTrim(Map<String, ?> map, String key, int defaultValue) {
        String value = getTrimmedValue(map, key);
        return NumberUtils.toInt(value, defaultValue);
    }

    // ==================== Long ====================

    /**
     * 获取Long参数，自动trim字符串并处理空值
     * @param map 参数Map
     * @param key 参数键
     * @param defaultValue 默认值
     * @return 转换后的Long，失败或空值返回默认值
     */
    public static long getLongWithTrim(Map<String, ?> map, String key, long defaultValue) {
        String value = getTrimmedValue(map, key);
        return NumberUtils.toLong(value, defaultValue);
    }

    // ==================== Boolean ====================

    /**
     * 获取Boolean参数，自动trim字符串并处理空值
     * 支持布尔值格式：true/false
     * @param map 参数Map
     * @param key 参数键
     * @param defaultValue 默认值
     * @return 转换后的Boolean，失败或空值返回默认值
     */
    public static boolean getBooleanWithTrim(Map<String, ?> map, String key, boolean defaultValue) {
        String value = getTrimmedValue(map, key);

        if (value == null) {
            return defaultValue;
        }

        switch (value.toLowerCase()) {
            case "true":
                return true;
            case "false":
                return false;
            default:
                return defaultValue;
        }
    }

    // ==================== 便捷方法 ====================

    /**
     * 获取String参数，自动trim并处理空值，默认值为null
     */
    public static String getStringWithTrim(Map<String, ?> map, String key) {
        return getStringWithTrim(map, key, null);
    }

    /**
     * 获取Integer参数，自动trim并处理空值，默认值为0
     */
    public static int getIntegerWithTrim(Map<String, ?> map, String key) {
        return getIntegerWithTrim(map, key, 0);
    }

    /**
     * 获取Long参数，自动trim并处理空值，默认值为0L
     */
    public static long getLongWithTrim(Map<String, ?> map, String key) {
        return getLongWithTrim(map, key, 0L);
    }

    /**
     * 获取Boolean参数，自动trim并处理空值，默认值为null
     */
    public static boolean getBooleanWithTrim(Map<String, ?> map, String key) {
        return getBooleanWithTrim(map, key, false);
    }

    // ==================== List<String> ====================

    /**
     * 将拼接的字符串按分隔符拆分为List<String>，自动trim每个元素
     * @param map 参数Map
     * @param key 参数键
     * @param delimiter 分隔符，如 ","、"|"
     * @param defaultValue 默认值
     * @return 拆分后的List，若原始值为空则返回默认值
     */
    public static List<String> getStringListWithTrim(Map<String, ?> map, String key, String delimiter, List<String> defaultValue) {
        String value = getTrimmedValue(map, key);
        if (value == null) {
            return defaultValue;
        }

        return Arrays.stream(value.split(delimiter))
                .map(String::trim)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList());
    }

    public static List<String> getStringListWithTrim(Map<String, ?> map, String key, String delimiter) {
        return getStringListWithTrim(map, key, delimiter, Collections.emptyList());
    }

    // ==================== List<Integer> ====================

    /**
     * 将拼接的数字字符串按分隔符拆分为List<Integer>，自动trim并转换每个元素
     * @param map 参数Map
     * @param key 参数键
     * @param delimiter 分隔符，如 ","、"|"
     * @param defaultValue 默认值
     * @return 拆分后的List，若原始值为空或转换失败则返回默认值
     */
    public static List<Integer> getIntegerListWithTrim(Map<String, ?> map, String key, String delimiter, List<Integer> defaultValue) {
        String value = getTrimmedValue(map, key);
        if (value == null) {
            return defaultValue;
        }

        List<Integer> result = Lists.newArrayList();
        for (String part : value.split(delimiter)) {
            String trimmed = part.trim();
            if (NumberUtils.isParsable(trimmed)) {
                result.add(NumberUtils.toInt(trimmed));
            }
        }

        return result.isEmpty() ? defaultValue : result;
    }

    public static List<Integer> getIntegerListWithTrim(Map<String, ?> map, String key, String delimiter) {
        return getIntegerListWithTrim(map, key, delimiter, Collections.emptyList());
    }

    // ==================== List<Long> ====================

    /**
     * 将拼接的数字字符串按分隔符拆分为List<Long>，自动trim并转换每个元素
     * @param map 参数Map
     * @param key 参数键
     * @param delimiter 分隔符，如 ","、"|"
     * @param defaultValue 默认值
     * @return 拆分后的List，若原始值为空或转换失败则返回默认值
     */
    public static List<Long> getLongListWithTrim(Map<String, ?> map, String key, String delimiter, List<Long> defaultValue) {
        String value = getTrimmedValue(map, key);
        if (value == null) {
            return defaultValue;
        }

        List<Long> result = Lists.newArrayList();
        for (String part : value.split(delimiter)) {
            String trimmed = part.trim();
            if (NumberUtils.isParsable(trimmed)) {
                result.add(NumberUtils.toLong(trimmed));
            }
        }

        return result.isEmpty() ? defaultValue : result;
    }

    public static List<Long> getLongListWithTrim(Map<String, ?> map, String key, String delimiter) {
        return getLongListWithTrim(map, key, delimiter, Collections.emptyList());
    }
}
